#property copyright "Copyright 2012"
#property link      "mingxinhe@gmail.com"

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Red
#property indicator_width1 1
#property indicator_color2 Green
#property indicator_width2 1
#property indicator_color3 LightSeaGreen
#property indicator_width3 1
#property indicator_color4 Red
#property indicator_width4 1
#property indicator_color5 LightSeaGreen
#property indicator_width5 1
#property indicator_color6 LightSeaGreen
#property indicator_width6 1

extern int EMA.Period=100;
extern string EMA.Applied.Price.Desc = "0:PRICE_CLOSE;1:PRICE_OPEN;2:PRICE_HIGH;3:PRICE_LOW";
extern int EMA.Applied.Price = 0;
extern int EMA.Shift=0;
extern int period = 20;
extern int deviation = 2;
extern int bands_shift = 0;
extern int applied_price = 0;
extern bool Text.Alert = true;
extern bool Sound.Alert = true;
extern bool Email.Alert = true;
extern string SoundFileName = "Alert.wav";

//---- buffers
double upArrow[];
double downArrow[];
//---- buffers
double EMABuffer[];
double MABuffer[];
double upperBuffer[];
double lowerBuffer[];

int digitFactor = 1;
datetime lastTime;
bool upArrowSignal = false;
bool downArrowSignal = false;

int  Pointer_Offset = 0;         // The offset value for the arrow to be located off the candle high or low point.
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
  //---- 6 additional buffers are used for counting.   
   if(Bid<10 && Digits==5) { digitFactor=10;}
   if(Bid<10 && Digits==4) { digitFactor= 1;}

   if(Bid>10 && Digits==3) { digitFactor=10;}
   if(Bid>10 && Digits==2) { digitFactor= 1;} 
  
   IndicatorBuffers(6);   
//---- drawing settings 
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,234);
   SetIndexBuffer(0, downArrow);
      
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,233);
   SetIndexBuffer(1, upArrow);      
      
   SetIndexBuffer(2,MABuffer);
   SetIndexBuffer(3,EMABuffer);  
   
   SetIndexBuffer(4,upperBuffer);
   SetIndexBuffer(5,lowerBuffer); 
   
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   
   lastTime = D'1977.01.01 00:00';      
   
//---- initialization done
   return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+

int deinit()
{
//---- TODO: add your code here
// --------------------------
//----
   return(0);
}

//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start()
{  
   double AvgRange;
   if (!isNewBar()) return;  

   if(Bars<=EMA.Period) return(0);
   
   int  counted_bars=IndicatorCounted();        
   if(counted_bars>0) 
   {
       int limit=Bars-counted_bars;
   }
   else
   {
       limit = Bars-EMA.Period+1;
   }       
      
   while(limit>=0)         
   {                     
       upArrow[limit+1] = 0;
       downArrow[limit+1] = 0;                
       
       EMABuffer[limit]=iMA(NULL,0,EMA.Period,EMA.Shift,1,EMA.Applied.Price,limit); 
       MABuffer[limit]=iMA(NULL,0,period,EMA.Shift,0,applied_price,limit);     
       
       upperBuffer[limit] = iBands(NULL, 0,  period, deviation, bands_shift, applied_price, MODE_UPPER, limit);
       lowerBuffer[limit] = iBands(NULL, 0,  period, deviation, bands_shift, applied_price, MODE_LOWER, limit);  
       
       AvgRange = 0;       
       for (int counter=limit+1 ;counter<=limit+10;counter++)
       {
           AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
       }
       double Range=AvgRange/10;
      
       if (MABuffer[limit] < EMABuffer[limit] && MABuffer[limit + 1] < EMABuffer[limit + 1] && MABuffer[limit + 2] < EMABuffer[limit + 2])
       {                        
                                            
           if ((Close[limit + 2] > upperBuffer[limit + 2] && Close[limit + 1] < Open[limit + 1] && Open[limit + 1] > upperBuffer[limit + 1] && Open[limit] < upperBuffer[limit]) ||
               (Close[limit + 1] < MABuffer[limit + 1] && Open[limit + 1] > MABuffer[limit + 1] && Close[limit + 2] > MABuffer[limit + 2] && Open[limit + 2] < MABuffer[limit + 2]))
           {
               downArrow[limit+1] = High[limit+1] + Range*0.3;
               string alertStr = "Pair:" + Symbol() + ", T/F:" +  getTimeFrame(Period()) + ", Direction: SHORT, Price:" + DoubleToStr(Bid, Digits);                   
               if (Text.Alert && limit == 0)
               {
                   Alert(alertStr);
                   Print(alertStr);
               }
               if (Email.Alert && limit == 0)
               {
                   SendMail("BBEMA SHORT Alert" , alertStr);  
               }
               if (Sound.Alert && limit == 0)
               {
                   PlaySound(SoundFileName);
               }                         
           }                                         
      }

      if (MABuffer[limit] > EMABuffer[limit] && MABuffer[limit + 1] > EMABuffer[limit + 1] && MABuffer[limit + 2] > EMABuffer[limit + 2])
      {     
           if ((Close[limit + 2] < lowerBuffer[limit + 2] && Close[limit + 1] > Open[limit + 1] && Open[limit + 1] < lowerBuffer[limit + 1] && Open[limit] > lowerBuffer[limit]) ||                            
               (Close[limit + 1] > MABuffer[limit + 1] && Open[limit + 1] < MABuffer[limit + 1] && Close[limit + 2] < MABuffer[limit + 2] && Open[limit + 2] > MABuffer[limit + 2]))
           {           
              upArrow[limit+1] = Low[limit+1] - Range*0.3;  
              alertStr = "Pair:" + Symbol() + ", T/F:" +  getTimeFrame(Period()) + ", Direction: LONG, Price:" + DoubleToStr(Ask, Digits);
               
              if (Text.Alert && limit == 0)
               {
                   Alert(alertStr);
                   Print(alertStr);
               }
               if (Email.Alert && limit == 0)
               {
                   SendMail("BBEMA LONG Alert" , alertStr);  
               }
               if (Sound.Alert && limit == 0)
               {
                   PlaySound(SoundFileName);
               }   
           }
                                         
      } 
      
      limit--;
   }
      
//---- done
   return(0);  
}
  
bool isNewBar()
{
    if (lastTime == Time[0]) return (false);   
    lastTime = Time[0];
    return (true); 
}

string getTimeFrame(int _Period)
{
    switch (_Period)
    {
        case 1: return ("M1");
                break;
        case 5: return ("M5");
                break;
        case 15: return ("M15");
                break;
        case 30: return ("M30");
                break;
        case 60: return ("H1");
                break;
        case 240: return ("H4");
                break;
        case 1440: return ("D1");
                break;
        case 10080: return ("W1");
                break;
        case 43200: return ("Month");
                break;
    }
}
 